package com.gopay.checkorder.service.task;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.service.CheckGopayOrderService;
import com.gopay.checkorder.service.task.thread.CheckGopayOrderTaskThread;
import com.gopay.common.domain.cps.CpsOrderAdjustRecord;
import com.gopay.common.util.ExecutorUtil;

public class CheckGopayOrderTaskImpl implements Task {
    private final static Logger logger = LoggerFactory.getLogger("CHECK_GOPAY_ORDER");

    private final static int MAX_SIZE = 10000;

    @Resource(name = "checkGopayOrderTaskThread")
    private CheckGopayOrderTaskThread checkGopayOrderTaskThread;

    @Resource(name = "checkGopayOrderService")
    private CheckGopayOrderService checkGopayOrderService;

    private String adjustResult;
    private int adjustCounts;

    @Override
    public void doTask() {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(4, 10, 3, TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(100), new ThreadPoolExecutor.CallerRunsPolicy());

        try{
	        int pageSize = 100;
	        int pageIndex = 1;
	        int count = 0;
	
	        int resCount = checkGopayOrderService.getUnCheckCount(adjustResult, adjustCounts);
	        if (resCount > MAX_SIZE) {
	            resCount = MAX_SIZE;
	        }
	
	        List<CpsOrderAdjustRecord> list = null;
	        while (count < resCount) {
	            list = checkGopayOrderService.getUnCheckList(adjustResult, adjustCounts, pageIndex, pageSize);
	            if (list == null || list.size() == 0) {
	                logger.error("no bankorder data.");
	            }
	
	            LinkedBlockingQueue<CpsOrderAdjustRecord> queue = new LinkedBlockingQueue<CpsOrderAdjustRecord>();
	            queue.addAll(list);
	
	            int size = queue.size();
	            CountDownLatch latch = new CountDownLatch(size);
	
	            checkGopayOrderTaskThread.setLatch(latch);
	            checkGopayOrderTaskThread.setQueue(queue);
	
	            for (int i = 0; i < list.size(); i++) {
	                threadPool.execute(checkGopayOrderTaskThread);
	            }
	
	            count += pageSize;
	            pageIndex++;
	
	            try {
	                latch.await(5, TimeUnit.MINUTES);
	            } catch (InterruptedException e) {
	                logger.error("CheckOrderTaskImpl doTask fail.", e);
	            }
	        }
        }catch (Throwable t) {
        	logger.error("执行Task时出现异常" ,t);
		}finally{
			ExecutorUtil.gracefulShutdown(threadPool, 1000 * 60 * 3);
		}
    }

    public void setAdjustResult(String adjustResult) {
        this.adjustResult = adjustResult;
    }

    public void setAdjustCounts(int adjustCounts) {
        this.adjustCounts = adjustCounts;
    }

}
